﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using Newtonsoft.Json.Linq;

namespace BugLabsLibrary
{
    public class BugLabsClient
    {
        #region *** Properties ***
        /// <summary>
        /// List of things managed by this client
        /// </summary>
        public List<DweetThing> Things { get; private set; }
        public bool IsEnabled { get; set; }
        #endregion

        #region *** Constructor ***
        /// <summary>
        /// Default Constructor
        /// </summary>
        public BugLabsClient()
        {
            IsEnabled = false;
            Things = new List<DweetThing>();   
        }
        #endregion

 

        #region *** API ***

        public DweetThing FindThingByName(string name)
        {
            foreach (DweetThing dt in Things)
                if (dt.ThingName == name)
                    return dt;
            return null;
        }

        public DweetThing FindThingByDeviceReference(string reference)
        {
            foreach (DweetThing dt in Things)
                if (dt.DeviceReference == reference)
                    return dt;
            return null;
        }
        /// <summary>
        /// Send data to Dweet/IO
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <param name="channelName">Name of channel containing the data.</param>
        /// <param name="data">Value</param>
        /// <returns>True if successful, false if not.</returns>
        public bool DweetFor(string thingName, string channelName, string data)
        {
            if (IsEnabled == false) return false;
            DweetThing thing = FindThingByName(thingName);
            if (thing == null)
                return false;
            string qry = Properties.Resources.DweetIoUrl + Properties.Resources.DweetForCommand + "/" + thingName + "?" +
                         channelName + "=" + data;

            // The response will be a "0" if there is an error or the entry_id if > 0
            string response = PostToBugLabs(qry);
            try
            {
                JObject ro = JObject.Parse(response);
                if ((string) ro["this"] == "succeeded")
                    return true;
            }
            catch(Exception ex)
            {}
            return false;
        }
        /// <summary>
        /// Gets the latest Dweet for a specific thing.
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <returns>Latest Dweet</returns>
        public Dweet GetLatestDweetFor(string thingName)
        {
            if (IsEnabled == false) return null;
            Dweet retVal = new Dweet();

            return retVal;
        }
        /// <summary>
        /// Gets all available Dweets for a specific thing.
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <returns>List of Dweets.</returns>
        public List<Dweet> GetDweetsFor(string thingName)
        {
            if (IsEnabled == false) return null;
            List<Dweet> retVal = new List<Dweet>();

            return retVal;
        }
        /// <summary>
        /// Creates an alert for a thing.
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <param name="toWhom">Comma separated list of email addresses.</param>
        /// <param name="condition">Condition causing alert. See dweet.io website for more information</param>
        /// <returns>True if successful, false if not.</returns>
        public bool CreateAlertFor(string thingName, string toWhom, string condition)
        {

            if (IsEnabled == false) return false;
            return false;
        }
        /// <summary>
        /// Gets an alert, if any, for a thing.
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <returns>Populates the alert information in the appropriate DweetThing and returns it to the caller.</returns>
        public DweetThing GetAlertFor(string thingName)
        {
            if (IsEnabled == false) return null;
            DweetThing retVal=null;

            return retVal;
        }
        /// <summary>
        /// Remove an alert from a thing
        /// </summary>
        /// <param name="thingName">Name of thing.  Must match a thing in Things.</param>
        /// <returns>True if successful, false if not.</returns>
        public bool RemoveAlertFor(string thingName)
        {
            return false;
        }
        /// <summary>
        /// Loads persisted data from a file.  This will include previously configured things
        /// </summary>
        /// <param name="fileNameWithPath">File name with path</param>
        public void LoadFromFile(string fileNameWithPath)
        {
            if (File.Exists(fileNameWithPath))
            {
                
            }
        }
        /// <summary>
        /// Saves list of things to a file.
        /// </summary>
        /// <param name="fileNameWithPath">File name with path</param>
        public void SaveToFile(string fileNameWithPath)
        {
            
        }
        #endregion

        #region *** Private Methods ***

        private static string PostToBugLabs(string QueryString)
        {
            StringBuilder sbResponse = new StringBuilder();
            byte[] buf = new byte[8192];

           

            try
            {            // Hit the URL with the querystring and put the response in webResponse
                HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(QueryString);
                myRequest.Timeout = 15000;
                HttpWebResponse webResponse = (HttpWebResponse)myRequest.GetResponse();
                Stream myResponse = webResponse.GetResponseStream();

                int count = 0;

                // Read the response buffer and return
                do
                {
                    count = myResponse.Read(buf, 0, buf.Length);
                    if (count != 0)
                    {
                        sbResponse.Append(Encoding.ASCII.GetString(buf, 0, count));
                    }
                }
                while (count > 0);
                return sbResponse.ToString();
            }
            catch (WebException ex)
            {
                return "0";
            }

        }

        #endregion
    }
}
